#ifndef __LIB_H
#define __LIB_H
#include <bpf/libbpf.h>

static struct bpf_object* load_and_attach_bpf_prog(const char *prog_name) {
        int ret;
        struct bpf_program *prog;
        struct bpf_object *obj;
        struct bpf_link *links;

        obj = bpf_object__open_file(prog_name, NULL);
        ret = libbpf_get_error(obj);
        if (ret) {
                printf("opening BPF object file failed(err = %d).\n", ret);
                goto err;
        }
        ret = bpf_object__load(obj);
        if (ret) {
                printf("Failed to load bpf prog(err = %d).\n", ret);
                goto err;
        }
        bpf_object__for_each_program(prog, obj) {
        links = bpf_program__attach(prog);
                ret = libbpf_get_error(links);
                if (ret) {
                        printf("attach bpf prog(%s) failed %d\n", prog_name, ret);
                        links = NULL;
                        goto err;
                }
        }
        return obj;
err:
        return NULL;
}

static struct bpf_object* load_bpf_prog(const char *prog_name) {
        int ret;
        struct bpf_program *prog;
        struct bpf_object *obj;
        struct bpf_link *links;

        obj = bpf_object__open_file(prog_name, NULL);
        ret = libbpf_get_error(obj);
        if (ret) {
                printf("opening BPF object file failed(err = %d).\n", ret);
                goto err;
        }
        ret = bpf_object__load(obj);
        if (ret) {
                printf("Failed to load bpf prog(err = %d).\n", ret);
                goto err;
        }
        return obj;
err:
        return NULL;
}


static struct bpf_program* get_prog_by_name(struct bpf_object* obj, const char *name) {
       struct bpf_program *prog;

        bpf_object__for_each_program(prog, obj) {
               if (strcmp(bpf_program__name(prog), name) == 0) {
                        return prog;
               }
        }
        return NULL;
}

static int attach_bpf_prog_by_name(struct bpf_object *obj, const char *name) {
        struct bpf_program *prog;
        struct bpf_link *links;
	int ret;

	prog = get_prog_by_name(obj, name);
	if (!prog) {
		return -1;	
	}
        links = bpf_program__attach(prog);
 	ret = libbpf_get_error(links);
        if (ret) {
        	printf("attach bpf prog(%s) failed %d\n", name, ret);
		links = NULL;
                goto err;
        }
        return 0;
err:
        return 1;
}

#endif
